package com.ruoyi.asset.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.asset.domain.BackFiles;
import com.ruoyi.asset.domain.BackMediaFile;
import com.ruoyi.asset.service.IBackFilesService;
import com.ruoyi.asset.service.IBackMediaFileService;
import com.ruoyi.asset.service.IMultipartFileService;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileTypeUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 文件操作服务实现
 *
 * @author zy
 */
@Service
public class MultipartFileServiceImpl implements IMultipartFileService {

    @Autowired
    private IBackFilesService backFilesService;
    @Autowired
    private IBackMediaFileService backMediaFileService;

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    @Override
    public AjaxResult uploadFile(MultipartFile file, Map req) {
        try {
            if (file.isEmpty()) {
                return AjaxResult.error("上传失败,上传文件为空!");
            }
            // 上传文件路径
            String uploadPath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String filePath = FileUploadUtils.upload(uploadPath, file);
            //上传成功，入库操作
            // 文件基础信息
            BackFiles bf = new BackFiles();
            bf.setFileName(file.getOriginalFilename());
            bf.setFileSize(file.getSize());
            bf.setFilePath(filePath);
            backFilesService.insertBackFiles(bf);
            // 添加fileId，并修改文件路径进行返回
            bf.setFilePath(RuoYiConfig.getProfile() + bf.getFilePath());
            return AjaxResult.success("上传成功", bf);
        } catch (Exception e) {
            e.printStackTrace();
            //手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("上传异常");
        }
    }

    @Override
    public AjaxResult uploadFileForOrder(MultipartFile file, Map req) {
        try {
            if (file.isEmpty()) {
                return AjaxResult.error("上传失败,上传文件为空!");
            }
            // 获取传参的报文数据
            String params = MapUtils.getString(req, "params");
            if (StringUtils.isBlank(params)) {
                return AjaxResult.error("缺失必要参数");
            }
            // 解析成json
            JSONObject attr = JSON.parseObject(params);
            // 通过文件原始名称获取参数
            if (MapUtils.isEmpty(attr) || !attr.containsKey("linkId")) {
                return AjaxResult.error("缺失必要参数");
            }
            // 上传文件路径
            String uploadPath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String filePath = FileUploadUtils.upload(uploadPath, file);
            // 文件基础信息
            BackFiles bf = new BackFiles();
            bf.setFileName(file.getOriginalFilename());
            bf.setFileSize(file.getSize());
            bf.setFilePath(filePath);
            backFilesService.insertBackFiles(bf);
            // 多媒体附件关联信息
            BackMediaFile bmf = new BackMediaFile();
            bmf.setLinkType("1");
            bmf.setLinkId(attr.getLong("linkId"));
            bmf.setFileType(FileTypeUtils.getFileTypeName(filePath));
            bmf.setFileId(bf.getFileId());
            backMediaFileService.insertBackMediaFile(bmf);
            // 添加fileId，并修改文件路径进行返回
            bf.setFilePath(RuoYiConfig.getProfile() + bf.getFilePath());
            return AjaxResult.success("上传成功", bf);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("上传异常");
        }
    }

    @Override
    public void downloadFile(Long fileId, HttpServletResponse response) throws IOException {
        BackFiles backFile = backFilesService.selectBackFilesByFileId(fileId);
        if (backFile == null) {
            response.getOutputStream().write("未找到该文件".getBytes(StandardCharsets.UTF_8));
            return;
        }
        // 文件路径
        String filePath = backFile.getFilePath();
        // 文件真实路径
        String fileRealPath = RuoYiConfig.getProfile() + filePath.replaceFirst(Constants.RESOURCE_PREFIX, "");
        // 文件名+后缀
        String fileName = backFile.getFileName() + filePath.substring(filePath.lastIndexOf("."));
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        FileUtils.setAttachmentResponseHeader(response, fileName);
        FileUtils.writeBytes(fileRealPath, response.getOutputStream());
    }

    @Override
    public AjaxResult removeFile(Long fileId) {
        // 只修改文件表状态为作废
        backMediaFileService.deleteBackMediaFileByFileId(fileId);
        backFilesService.deleteBackFilesByFileId(fileId);
        return AjaxResult.success("删除成功");
    }
}
